#include "bsp_motor.h"

#define POSITIVE    1//定义电机状态 前进
#define REVERSE  2//后退
#define STOP  0//停车

/* 带参宏，可以像内联函数一样使用 */
#define AIN1(a)	if (a)	\
					GPIO_SetBits(GPIOC,GPIO_Pin_0);\
					else		\
					GPIO_ResetBits(GPIOC,GPIO_Pin_0)

#define BIN1(a)	if (a)	\
					GPIO_SetBits(GPIOC,GPIO_Pin_1);\
					else		\
					GPIO_ResetBits(GPIOC,GPIO_Pin_1)
#define CIN1(a)	if (a)	\
					GPIO_SetBits(GPIOC,GPIO_Pin_2);\
					else		\
					GPIO_ResetBits(GPIOC,GPIO_Pin_2)

#define DIN1(a)	if (a)	\
					GPIO_SetBits(GPIOC,GPIO_Pin_3);\
					else		\
					GPIO_ResetBits(GPIOC,GPIO_Pin_3)
					

/**
1PA PC0 普通IO
1PB PC6 TIM8_CH1 PWM
2PA PC1 普通IO
2PB PC7 TIM8_CH2 PWM
3PA PC2 普通IO
3PB PC8 TIM3_CH3 PWM
4PA PC3 普通IO
4PB PC9 TIM3_CH3 PWM
 */

void bsp_motor_init(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;

    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);

    GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);
    GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;	    /*选择要控制的GPIO引脚*/	
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;           
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);                                                 /*调用库函数，初始化GPIO*/	

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    // PWM的频率 = 72MHz/ARR/PCS 例如  20K = 168M/5400/1 = 20K
	TIM_TimeBaseStructure.TIM_Period = 4000-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         80K
	TIM_TimeBaseStructure.TIM_Prescaler = 42-1; //设置用来作为TIMx时钟频率除数的预分频值  不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //高级定时器1是用定时器功能配置这个才可以是正常的计数频率一开始的72mhz 值得注意的地方      
	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    // TIM_ARRPreloadConfig(TIM8, ENABLE);

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset ;
	TIM_OCInitStructure.TIM_Pulse = 50; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH1预装载使能       

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset ;
	TIM_OCInitStructure.TIM_Pulse = 50; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC2Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH2预装载使能       

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset ;
	TIM_OCInitStructure.TIM_Pulse = 50; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC3Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH3预装载使能       

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset ;
	TIM_OCInitStructure.TIM_Pulse = 50; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC4Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH4预装载使能       

	TIM_ARRPreloadConfig(TIM8, ENABLE);              //使能TIMx在ARR上的预装载寄存器

	TIM_Cmd(TIM8, ENABLE);  //使能TIM8
	TIM_CtrlPWMOutputs(TIM8,ENABLE);        //MOE 主输出使能                           //启动定时	


}

//以下单独定义每个轮子运动状态，如果不对可以修改里面的参数
//比如左轮前进，AIN1（0），AIN2（1）.如果往后转了，就改成AIN1（1），AIN2（0）

//***************************占空比调节***************************//
//占空比 = TIMx_CCRx / TIMx_ARR
//数值 0-3600
void A4950_PWM_OutA(u16 motorA)
{
	TIM8 -> CCR1 = motorA;
}	
void A4950_PWM_OutB(u16 motorB)
{
	
	TIM8 -> CCR2 = motorB;                //启动自动重装	 
}
void A4950_PWM_OutC(u16 motorC)
{
	
	TIM8 -> CCR3 = motorC;
}	

void A4950_PWM_OutD(u16 motorD)
{
	TIM8 -> CCR4 = motorD;
}


//以下单独定义每个轮子运动状态，如果不对可以修改里面的参数
//state  GO:前进，BACK：后退，STOP：停止
//pwm:占空比调节：0-3600
void MotorA_Control(u8 state,u16 pwm)
{
	if(state == POSITIVE)      //电机A前进
	{
	  A4950_PWM_OutA(pwm);
		AIN1(0);
	}
	if(state == REVERSE)   //电机A后退
	{
		A4950_PWM_OutA(4000-pwm);
		AIN1(1);
	}
	if(state == STOP)  //停转
	{
	  A4950_PWM_OutA(0);
		AIN1(0);
	}
}

void MotorB_Control(u8 state,u16 pwm)
{
	if(state == POSITIVE)      //电机B前进
	{
	  A4950_PWM_OutB(pwm);
		BIN1(0);
	}
	if(state == REVERSE)   //电机B后退
	{
		A4950_PWM_OutB(4000-pwm);
		BIN1(1);
	}
	if(state == STOP)  //停转
	{
	  A4950_PWM_OutB(0);
		BIN1(0);
	}
}
void MotorC_Control(u8 state,u16 pwm)
{
	if(state == POSITIVE)      //电机C前进
	{
	  A4950_PWM_OutC(pwm);
		CIN1(0);
	}
	if(state == REVERSE)   //电机C后退
	{
		A4950_PWM_OutC(4000-pwm);
		CIN1(1);
	}
	if(state == STOP)  //停转
	{
	  A4950_PWM_OutC(0);
		CIN1(0);
	}
}

void MotorD_Control(u8 state,u16 pwm)
{
	if(state == POSITIVE)      //电机D前进
	{
	  A4950_PWM_OutD(pwm);
		DIN1(0);
	}
	if(state == REVERSE)   //电机D后退
	{
		A4950_PWM_OutD(4000-pwm);
		DIN1(1);
	}
	if(state == STOP)  //停转
	{
	  A4950_PWM_OutD(0);
		DIN1(0);
	}
}
